package com.mydemo.springlearning.functions.reflection.api;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;

/**
 * @author hd
 * @date 2022-07-23 14:09
 * @description
 */
public class TestReflectionClass {

    public static void main(String[] args) {
        printFields();
        System.out.println("===================================================================");
        printMethods();
    }


    /**
     * 通过反射获取类的所有变量
     * 结果：
     * getModifiers()：子类中的public 成员变量 子类继承父类的public 成员变量
     * getDeclaredFields()：本类不管修饰符的成员变量，不含继承下的
     */
    private static void printFields() {
        //1.获取并输出类的名称
        Class<SonClass> mClass = SonClass.class;
        System.out.println("类的名称：" + mClass.getName());

        //2.1 获取所有 public 访问权限的变量
        // 包括本类声明的和从父类继承的
        Field[] fields = mClass.getFields();

        //3. 遍历变量并输出变量信息
        for (Field field : fields) {
            //获取访问权限并输出
            int modifiers = field.getModifiers();
            System.out.print("访问修饰符：" + Modifier.toString(modifiers) + " 类名:");
            //输出变量的类型及变量名
            System.out.println(field.getType().getName() + " 方法名:" + field.getName());
        }
        System.out.println(" ");
        //2.2 获取所有本类声明的变量（不管访问权限）

        Field[] fieldsFull = mClass.getDeclaredFields();
        for (Field field : fieldsFull) {
            //获取访问权限并输出
            int modifiers = field.getModifiers();
            System.out.print("访问修饰符：" + Modifier.toString(modifiers) + " 类名:");
            //输出变量的类型及变量名
            System.out.println(field.getType().getName() + " 方法名:" + field.getName());
        }
    }

    /**
     * 通过反射获取类的所有方法
     */
    private static void printMethods() {
        //1.获取并输出类的名称
        Class<SonClass> mClass = SonClass.class;
        System.out.println("类的名称：" + mClass.getName());

        //2.1 获取所有 public 访问权限的方法
        //包括自己声明和从父类继承的
        Method[] mMethods = mClass.getMethods();


        System.out.println("================================ getMethods ================================");
        //3.遍历所有方法
        for (Method method : mMethods) {
            //获取并输出方法的访问权限（Modifiers：修饰符）
            int modifiers = method.getModifiers();
            System.out.print("修饰符：" + Modifier.toString(modifiers) + " 返回值类型：");
            //获取并输出方法的返回值类型
            Class returnType = method.getReturnType();
            System.out.print(" " + returnType.getName() + " 方法名：" + method.getName() + "( ");
            //获取并输出方法的所有参数
            Parameter[] parameters = method.getParameters();
            for (int i = 0; i < parameters.length; i++) {
                System.out.print("参数" + (i + 1) + " " + parameters[i].getType().getName() + " " + parameters[i].getName() + (i == (parameters.length - 1) ? "" : ","));
            }
            //获取并输出方法抛出的异常
            Class[] exceptionTypes = method.getExceptionTypes();
            if (exceptionTypes.length == 0) {
                System.out.println(" )");
            } else {
                for (Class c : exceptionTypes) {
                    System.out.println(" ) throws 异常类型 " + c.getName());
                }
            }
        }
        System.out.println("================================ getDeclaredMethods ================================");
        //2.2 获取所有本类的的方法（不问访问权限）
        Method[] mMethodsAll = mClass.getDeclaredMethods();
        for (Method method : mMethodsAll) {
            //获取并输出方法的访问权限（Modifiers：修饰符）
            int modifiers = method.getModifiers();
            System.out.print("修饰符：" + Modifier.toString(modifiers) + " 返回值类型：");
            //获取并输出方法的返回值类型
            Class returnType = method.getReturnType();
            System.out.print(" " + returnType.getName() + " 方法名：" + method.getName() + "( ");
            //获取并输出方法的所有参数
            Parameter[] parameters = method.getParameters();
            for (int i = 0; i < parameters.length; i++) {
                System.out.print("参数" + (i + 1) + " " + parameters[i].getType().getName() + " " + parameters[i].getName() + (i == (parameters.length - 1) ? "" : ","));
            }
            //获取并输出方法抛出的异常
            Class[] exceptionTypes = method.getExceptionTypes();
            if (exceptionTypes.length == 0) {
                System.out.println(" )");
            } else {
                for (Class c : exceptionTypes) {
                    System.out.println(" ) throws 异常类型 " + c.getName());
                }
            }
        }
    }
}
